<?php
namespace App\Services;
use GuzzleHttp\Client;
use App\Models\Officialusersinfo;
use Illuminate\Support\Facades\Storage;
use EasyWeChat\Factory;
use App\Services\ThirdapiService;
use Illuminate\Support\Facades\Redis;
use Log,Exception,Config;
use Symfony\Component\Cache\Adapter\RedisAdapter;

class MiniappService
{
    /**
    * 修改symfony/cache缓存方式为redis
    */
    public static function miniProgram($appid,$secret)
    {
        $config = [
            'app_id' => $appid,
            'secret' => $secret,
            'response_type' => 'object',
        ];
        $miniapp = Factory::miniProgram($config);
        $predis = app('redis')->connection()->client();
        $cache = new RedisAdapter($predis);
        $miniapp->rebind('cache', $cache);
        return $miniapp;
    }

    public static function miniappAccessToken($appid,$secret,$force=false)
    {
        try {
            $official = self::miniProgram($appid,$secret);
            $accessToken = $official->access_token;
            if ($force) {
                $token = $accessToken->getToken(true);
            } else {
                $token = $accessToken->getToken();
            }
            return $token;
        } catch (Exception $e) {
            try{
                $message = $e->getMessage();
                $messagejson = explode("{", $message);
                $messagedata = json_decode("{".$messagejson[1]);
                return ["errcode"=>$messagedata->errcode,"errmsg"=>$messagedata->errmsg];
            } catch (Exception $es) { 
                return ["errcode"=>40011,"errmsg"=>""];
            }
        }
    }

    public static function getFixdScheme($appid,$secret,$path,$query)
    {
        $AccessToken = self::miniappAccessToken($appid,$secret);
        if (isset($AccessToken["access_token"])) {
            $generate =  self::urlSchemeCreat($AccessToken["access_token"],$path,$query);
            if ($generate["status"] == "success") return $generate;
            // 如果accesstoken过期重新生成
            if ($generate["code"] == 40001) {
                $AccessToken = self::miniappAccessToken($appid,$secret,true);
                $generate =  self::urlSchemeCreat($AccessToken["access_token"],$path,$query);
            }
            return $generate;
        } else {
            if ($AccessToken["errcode"] == 40013) return ["status"=>"error","code"=>40013,"msg"=>"小程序Appid错误,请确认Appid正确且小程序已上线！"];
            if ($AccessToken["errcode"] == 40125) return ["status"=>"error","code"=>40125,"msg"=>"小程序Appsecret错误,请修改后重新提交！"];
            if ($AccessToken["errcode"] == 50002) return ["status"=>"error","code"=>50002,"msg"=>"小程序已被注销或封禁,请修改小程序！"];
            return ["status"=>"error","code"=>40013,"msg"=>"小程序出现其他错误1！"];
        }
    }

    public static function getUrlScheme($appid,$secret,$path,$query)
    {
        $AccessToken = self::miniappAccessToken($appid,$secret);
        if (isset($AccessToken["access_token"])) {
            $AccessToken = self::miniappAccessToken($appid,$secret);
            $generate =  self::urlSchemeCreat($AccessToken["access_token"],$path,$query);
            if ($generate["status"] == "success") return $generate;
            // 如果accesstoken过期重新生成
            if ($generate["code"] == 40001) {
                $AccessToken = self::miniappAccessToken($appid,$secret,true);
                $generate =  self::urlSchemeCreat($AccessToken["access_token"],$path,$query);
            }
            return $generate;
        } else {
            if ($AccessToken["errcode"] == 40013) return ["status"=>"error","code"=>40013,"msg"=>"小程序Appid错误,请确认Appid正确且小程序已上线！"];
            if ($AccessToken["errcode"] == 40001) return ["status"=>"error","code"=>40001,"msg"=>"AppSecret 错误或者 AppSecret 不属于这个小程序！"];
            if ($AccessToken["errcode"] == 40125) return ["status"=>"error","code"=>40125,"msg"=>"小程序Appsecret错误,请修改后重新提交！"];
            if ($AccessToken["errcode"] == 50002) return ["status"=>"error","code"=>50002,"msg"=>"小程序已被注销或封禁,请修改小程序！"];
            if ($AccessToken["errcode"] == 40164) return ["status"=>"error","code"=>40164,"msg"=>"小程序未设置IP白名单,请在小程序后台关闭IP限制！"];
            return ["status"=>"error","code"=>40013,"msg"=>"小程序出现其他错误1！"];
        }
    }

    // 通过调用三方API获取token
    public static function apiTypeUrlScheme($appid,$path,$query)
    {
        $accessToken = Redis::get("miniapp_api_token_".$appid);
        if (empty($accessToken)) {
            $accessToken = ThirdapiService::apiGetThirdAccessToken($appid);
            if ($accessToken["status"] == "error") return ["status"=>"error","code"=>40013,"msg"=>$accessToken["msg"]];
        } else {
            $accessToken = json_decode($accessToken,true);
            if ($accessToken["expire_time"] <= time()) {
                $accessToken = ThirdapiService::apiGetThirdAccessToken($appid);
                if ($accessToken["status"] == "error") return ["status"=>"error","code"=>40013,"msg"=>$accessToken["msg"]];
            }
        }

        $generate =  self::urlSchemeCreat($accessToken["access_token"],$path,$query);
        if ($generate["status"] == "success") return $generate;
        // 如果accesstoken过期重新生成
        if ($generate["code"] == 40001) {
            $accessToken = ThirdapiService::apiGetThirdAccessToken($appid);
            if ($accessToken["status"] == "error") return ["status"=>"error","code"=>40013,"msg"=>$accessToken["msg"]];
            $generate =  self::urlSchemeCreat($accessToken["access_token"],$path,$query);
        }
        return $generate;
    }

    public static function getUrlLink($appid,$secret,$path,$query)
    {
        $AccessToken = self::miniappAccessToken($appid,$secret);
        if (isset($AccessToken["access_token"])) {
            $AccessToken = self::miniappAccessToken($appid,$secret);
            $generate =  self::urlLinkCreat($AccessToken["access_token"],$path,$query,time()+3600);
            if ($generate["status"] == "success") return $generate;
            // 如果accesstoken过期重新生成
            if ($generate["code"] == 40001) {
                $AccessToken = self::miniappAccessToken($appid,$secret,true);
                $generate =  self::urlLinkCreat($AccessToken["access_token"],$path,$query,time()+3600);
            }
            return $generate;
        } else {
            if ($AccessToken["errcode"] == 40013) return ["status"=>"error","code"=>40013,"msg"=>"小程序Appid错误,请确认Appid正确且小程序已上线！"];
            if ($AccessToken["errcode"] == 40001) return ["status"=>"error","code"=>40001,"msg"=>"AppSecret 错误或者 AppSecret 不属于这个小程序！"];
            if ($AccessToken["errcode"] == 40125) return ["status"=>"error","code"=>40125,"msg"=>"小程序Appsecret错误,请修改后重新提交！"];
            if ($AccessToken["errcode"] == 50002) return ["status"=>"error","code"=>50002,"msg"=>"小程序已被注销或封禁,请修改小程序！"];
            if ($AccessToken["errcode"] == 40164) return ["status"=>"error","code"=>40164,"msg"=>"小程序未设置IP白名单,请在小程序后台关闭IP限制！"];
            return ["status"=>"error","code"=>40013,"msg"=>"小程序出现其他错误1！"];
        }
    }

    // 创建urlscheme
    // https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/url-scheme/urlscheme.generate.html
    public static function urlSchemeCreat($access_token,$path,$querys)
    {
        $client = new Client();
        $req = $client->request('POST', 'https://api.weixin.qq.com/wxa/generatescheme?access_token='.$access_token, [
            'json' => ['jump_wxa' => ['path'=>$path,'query'=>$querys],'expire_type'=>1,'expire_interval'=>30]
        ]);
        $newinfo = $req->getBody();
        $info = json_decode($newinfo);
        if ($info->errmsg == "ok") {
            $openlink = $info->openlink;
            return ["status"=>"success","msg"=>"创建成功！","urlscheme"=>$openlink];
        } else {
            if ($info->errcode == 85079) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序未上线,无法访问！"];
            if ($info->errcode == 40165) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序路径不存在,您可以不填直接跳首页！"];
            if ($info->errcode == 40002) return ["status"=>"error","code"=>$info->errcode,"msg"=>"个人微信小程序暂无生成权限,请使用企业微信小程序！"];
            if ($info->errcode == 40013) return ["status"=>"error","code"=>$info->errcode,"msg"=>"您的小程序生成权限被封禁,请更换小程序！"];
            if ($info->errcode == 40165) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序路径path填写错误,请检查是否正确；如有疑问请联系客服！"];
            if ($info->errcode == 40212) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序路径query填写错误,请检查是否正确；如有疑问请联系客服！"];
            if ($info->errcode == 44990) return ["status"=>"error","code"=>$info->errcode,"msg"=>"生成Scheme频率过快,请稍后生成！"];
            if ($info->errcode == 85400) return ["status"=>"error","code"=>$info->errcode,"msg"=>"长期有效Scheme达到生成上限10万！"];
            if ($info->errcode == 45009) return ["status"=>"error","code"=>$info->errcode,"msg"=>"单天生成Scheme数量超过上限50万！"];
            // 本情况可能是没有设置白名单或者多个程序一直刷新Token
            if ($info->errcode == 40001) return ["status"=>"error","code"=>$info->errcode,"msg"=>"AccessToken已过期,请联系客服处理！"];
            if ($info->errcode == 42001) return ["status"=>"error","code"=>$info->errcode,"msg"=>"AccessToken已过期,请联系客服处理！"];
            if ($info->errcode == 48001) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序未授权！"];
            if ($info->errcode == 50002) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序已被注销或封禁,请修改小程序！"];
            if ($info->errcode == 61004) return ["status"=>"error","code"=>$info->errcode,"msg"=>"当前IP无法生成Scheme！"];
            if ($info->errcode == 61007) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序未授权给天天外链或者取消授权！"];
            Log::info("urlSchemeCreat------");
            Log::info(json_encode($info));
            Log::info("urlSchemeCreat------");
            return ["status"=>"error","code"=>4001,"msg"=>"创建外链异常,请联系客服！"];
        }
    }

    // 创建urllink
    // https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/url-link/urllink.generate.html
    public static function urlLinkCreat($access_token,$path,$querys,$expire_time)
    {
        $client = new Client();
        $req = $client->request('POST', 'https://api.weixin.qq.com/wxa/generate_urllink?access_token='.$access_token, [
            'json' => ['path'=>$path,'query'=>$querys,'expire_time'=>$expire_time]
        ]);
        $newinfo = $req->getBody();
        $info = json_decode($newinfo);
        if ($info->errmsg == "ok") {
            $url_link = $info->url_link;
            return ["status"=>"success","msg"=>"创建成功！","url_link"=>$url_link];
        } else {
            if ($info->errcode == 85079) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序未上线,无法访问！"];
            if ($info->errcode == 40165) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序路径不存在,您可以不填直接跳首页！"];
            if ($info->errcode == 40002) return ["status"=>"error","code"=>$info->errcode,"msg"=>"个人微信小程序暂无生成权限,请使用企业微信小程序！"];
            if ($info->errcode == 40013) return ["status"=>"error","code"=>$info->errcode,"msg"=>"您的小程序生成权限被封禁,请更换小程序！"];
            if ($info->errcode == 40165) return ["status"=>"error","code"=>$info->errcode,"msg"=>"参数path填写错误,可以咨询客服！"];
            if ($info->errcode == 40212) return ["status"=>"error","code"=>$info->errcode,"msg"=>"参数query填写错误,可以咨询客服！"];
            if ($info->errcode == 44990) return ["status"=>"error","code"=>$info->errcode,"msg"=>"生成Scheme频率过快,请稍后生成！"];
            if ($info->errcode == 85400) return ["status"=>"error","code"=>$info->errcode,"msg"=>"长期有效Scheme达到生成上限10万！"];
            if ($info->errcode == 45009) return ["status"=>"error","code"=>$info->errcode,"msg"=>"单天生成Scheme数量超过上限50万！"];
            // 本情况可能是没有设置白名单或者多个程序一直刷新Token
            if ($info->errcode == 40001) return ["status"=>"error","code"=>$info->errcode,"msg"=>"AccessToken已过期,请联系客服处理！"];
            if ($info->errcode == 48001) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序未授权！"];
            if ($info->errcode == 50002) return ["status"=>"error","code"=>$info->errcode,"msg"=>"小程序已被注销或封禁,请修改小程序！"];
            Log::info("urlLinkCreat------");
            Log::info(json_encode($info));
            Log::info("urlLinkCreat------");
            return ["status"=>"error","code"=>4001,"msg"=>"创建外链异常,请联系客服！"];
        }
    }

    // 创建小程序码
    // https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.createQRCode.html
    public static function createWxAqrcode($access_token,$path,$width)
    {
        $client = new Client();
        $params = ["path"=>$path,"width"=>$width];
        $response = $client->request('POST', 'https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token='.$access_token, [
            'body' => json_encode($params,JSON_UNESCAPED_UNICODE),
            'headers' => [
                'Content-type'=> 'application/json',
                'Accept'=>'application/json'
            ]]);
        $body = $response->getBody()->getContents();
        return $body;
    }

    // 永久小程序码
    // https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.get.html
    public static function getWxacode($access_token,$path,$width)
    {
        $client = new Client();
        $params = ["path"=>$path,"width"=>$width];
        $response = $client->request('POST', 'https://api.weixin.qq.com/wxa/getwxacode?access_token='.$access_token, [
            'body' => json_encode($params,JSON_UNESCAPED_UNICODE),
            'headers' => [
                'Content-type'=> 'application/json',
                'Accept'=>'application/json'
            ]]);
        $body = $response->getBody()->getContents();
        return $body;
    }

    // 适用于需要的码数量极多，或仅临时使用的业务场景
    // https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html
    public static function getWxacodeUnlimit($access_token,$path,$width,$auto_color,$line_color,$is_hyaline,$scene)
    {
        $client = new Client();
        $params = ["page"=>$path,"scene"=>$scene,"width"=>$width,"auto_color"=>$auto_color,"line_color"=>$line_color,"is_hyaline"=>$is_hyaline];
        $response = $client->request('POST', 'https://api.weixin.qq.com/wxa/getwxacode?access_token='.$access_token, [
            'body' => json_encode($params,JSON_UNESCAPED_UNICODE),
            'headers' => [
                'Content-type'=> 'application/json',
                'Accept'=>'application/json'
            ]]);
        $body = $response->getBody();
        return $body;
    }
}
